/*
 * Copyright (c) 2009 Tim Mead
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 */

/**
 * Cairngorm model.
 */
package com.misoneism.fire.model
{
	import com.adobe.air.preferences.Preference;
	import com.adobe.cairngorm.model.IModelLocator;
	import com.google.maps.LatLng;
	import com.misoneism.fire.rssprocessor.RSSProcessorResponder;
	import com.misoneism.fire.views.MapDisplay;
	
	import flash.data.SQLConnection;
	import flash.utils.Timer;
	
	import mx.binding.utils.BindingUtils;
	import mx.collections.ArrayCollection;
	
	import org.springextensions.actionscript.context.support.XMLApplicationContext;
	
	public class ModelLocator
			implements IModelLocator
	{
		protected static var inst:ModelLocator;
		
		/** The Spring application context. */
		[Bindable] public var applicationContext:XMLApplicationContext;
		
		/** Application database reference. */
		[Bindable] public var dbConnection:SQLConnection;
		
		/** Application prefrences. */
		[Bindable] public var preferences:Preference;
		
		/** Text to display on status bar. */
		[Bindable] public var statusMessage:String;
		
		/** Is an RSS feed being loaded? */
		[Bindable] public var feedLoading:Boolean;
		
		/** Responder for the RSS feed processor. */
		[Bindable] public var rssProcessorResponder:RSSProcessorResponder;
		
		/** Set of current incidents. */
		[Bindable] public var currentIncidents:ArrayCollection /* of Incident */;
		
		/** Reference to the map view. */
		[Bindable] public var mapDisplay:MapDisplay;
		
		/** Is the map active for use? */
		[Bindable] public var mapActive:Boolean;
		
		/** Is the map ready to use? */
		[Bindable] public var mapReady:Boolean;
		
		/** Is the address-lookup Geocoder busy? */
		[Bindable] public var mapAddressGeocoderBusy:Boolean;
		
		/** Timer used to fire off map updates. */
		public var updateTimer:Timer;
		
		/** How often to update the map. */
		private var _updateInterval:Number;
		
		/** The default location to centre on when opening the map. */
		private var _defaultLocation:LatLng;
		
		/** The default zoom level to display on the map. */
		private var _defaultZoom:Number;
		
		/**
		 * Singleton access method.
		 */
		public static function getInstance():ModelLocator
		{
			if (inst == null)
			{
				inst = new ModelLocator();
			}
			return inst;
		}
		
		public function ModelLocator()
		{
			BindingUtils.bindSetter(processMapActive, this, "mapReady");
			BindingUtils.bindSetter(processMapActive, this, "mapAddressGeocoderBusy");
		}
		
		[Bindable]
		public function get updateInterval():Number
		{
			if (isNaN(_updateInterval))
				_updateInterval = preferences.getValue("updateInterval", 300000);
			
			return _updateInterval;
		}
		public function set updateInterval(value:Number):void
		{
			preferences.setValue("updateInterval", value);
			_updateInterval = value;
		}
		
		[Bindable]
		public function get defaultLocation():LatLng
		{
			if (_defaultLocation == null)
				_defaultLocation = preferences.getValue("defaultLocation",
					MapDisplay.DEFAULT_LOCATION);
					
			return _defaultLocation;
		}
		public function set defaultLocation(value:LatLng):void
		{
			preferences.setValue("defaultLocation", value);
			_defaultLocation = value;
		}
		
		[Bindable]
		public function get defaultZoom():Number
		{
			if (isNaN(_defaultZoom))
				_defaultZoom = preferences.getValue("defaultZoom",
					MapDisplay.DEFAULT_ZOOM);
					
			return _defaultZoom;
		}
		public function set defaultZoom(value:Number):void
		{
			preferences.setValue("defaultZoom", value);
			_defaultZoom = value;
		}
		
		/**
		 * Compute whether the map is being processed or not (compound
		 * binding statement).
		 */
		private function processMapActive(o:Object):void
		{
			mapActive = mapReady && !mapAddressGeocoderBusy;
		}
	}
}